// 
//  DotNetNuke? - http://www.dotnetnuke.com
//  Copyright (c) 2002-2006
//  by DotNetNuke Corporation
// 
//  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
//  documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
//  the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
//  to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// 
//  The above copyright notice and this permission notice shall be included in all copies or substantial portions 
//  of the Software.
// 
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
//  TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
//  CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
//  DEALINGS IN THE SOFTWARE.
// 
using System;
using System.Web;
using System.Web.Compilation;
using System.Data;
using System.Reflection;
using System.Collections.Generic;
using DotNetNuke;
using System.Collections;
using System.Text;
using System.Data.SqlClient;
using DotNetNuke.Entities.Portals;
using Microsoft.VisualBasic;

namespace DotNetNuke.Modules.IWebCSharp
{
    public class IWEBMethods
    {
        public void AddandDeleteMethods()
        {
            //  Get Portals to remove
            System.Array arrPortalsOnServer;
            ArrayList PortalsWithoutMethods = new ArrayList();
            List<IWEBMethodInfo> lstAssemblies;
            ArrayList IWEBMethods;
            string strDescription;

            lstAssemblies = GetAssemblies();
            arrPortalsOnServer = PortalsOnServer();

            // Remove entries that no longer exist
            RemoveEntries(arrPortalsOnServer, lstAssemblies);

            // Add Methods

            //  * Loop through each portal
            foreach (int intPortalID in arrPortalsOnServer)
            {
                //  Get Methods for Portal
                IWEBMethods = GetMethodsInDatabase(intPortalID);

                foreach (IWEBMethodInfo objIWEBMethodInfo in lstAssemblies)
                {
                    //  * If the assembly is not in the portal add it
                    if (IWEBMethods.IndexOf(objIWEBMethodInfo.MethodName) == -1)
                    {
                        IWEBMethodInfo obj2IWEBMethodInfo = new IWEBMethodInfo();
                        obj2IWEBMethodInfo.Portal = intPortalID;
                        obj2IWEBMethodInfo.MethodName = Strings.Left(objIWEBMethodInfo.MethodName, 150);
                        obj2IWEBMethodInfo.MethodDescription = Strings.Left(objIWEBMethodInfo.MethodDescription, 1000);
                        obj2IWEBMethodInfo.SecuritySetting = "Host";
                        obj2IWEBMethodInfo.CompanyName = ExtractGroup(obj2IWEBMethodInfo.MethodDescription, "*");
                        obj2IWEBMethodInfo.ApplicationName = ExtractGroup(obj2IWEBMethodInfo.MethodDescription, "|");
                        obj2IWEBMethodInfo.FirstGrouping = ExtractGroup(obj2IWEBMethodInfo.MethodDescription, "#");
                        obj2IWEBMethodInfo.SecondGrouping = ExtractGroup(obj2IWEBMethodInfo.MethodDescription, "!");

                        if (obj2IWEBMethodInfo.MethodDescription != "")
                        {
                            strDescription = obj2IWEBMethodInfo.MethodDescription.Replace("*" + obj2IWEBMethodInfo.CompanyName + "*", "");
                            strDescription = strDescription.Replace("|" + obj2IWEBMethodInfo.ApplicationName + "|", "");
                            strDescription = strDescription.Replace("#" + obj2IWEBMethodInfo.FirstGrouping + "#", "");
                            strDescription = strDescription.Replace("!" + obj2IWEBMethodInfo.SecondGrouping + "!", "");
                            obj2IWEBMethodInfo.MethodDescription = strDescription;
                        }

                        AddMethod(obj2IWEBMethodInfo);
                    }
                }

            }

        }


        #region '"RemovePortals"'
        public void RemoveEntries(System.Array PortalsOnServer, List<IWEBMethodInfo> colAssemblies)
        {
            string strPortals = "";
            string strMethods = "";

            // Build Where clause
            foreach (int intPortal in PortalsOnServer)
            {
                strPortals += intPortal.ToString() + ",";
            }

            if (strPortals != "")
            {
                // Strip off the last comma
                strPortals = strPortals.Substring(0, (strPortals.Length - 1));
            }

            foreach (IWEBMethodInfo objIWEBMethodInfo in colAssemblies)
            {
                strMethods += "'" + objIWEBMethodInfo.MethodName.Replace("'", "") + "',";
            }

            if (strMethods != "")
            {
                // Strip off the last comma
                strMethods = strMethods.Substring(0, (strMethods.Length - 1));
            }

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("Delete ");
            mySqlString.Append("FROM {databaseOwner}{objectQualifier}IWebCSharpMethods ");
            mySqlString.Append("Where PortalID not in (" + strPortals + ") ");
            mySqlString.Append("Or MethodName not in (" + strMethods + ")");

            DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), null);
        }

        #endregion

        #region '"AddMethod"'
        public void AddMethod(IWEBMethodInfo objIWEBMethodInfo)
        {

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("INSERT INTO {databaseOwner}{objectQualifier}IWebCSharpMethods ");
            mySqlString.Append("(PortalID, MethodName, MethodDescription, SecuritySetting, CompanyName, ApplicationName, FirstGrouping, SecondGrouping) ");
            mySqlString.Append("VALUES (@PortalID,@MethodName,@MethodDescription,@SecuritySetting,@CompanyName,@ApplicationName,@FirstGrouping,@SecondGrouping)");

            SqlParameter prmPortalID = new SqlParameter("@PortalID", SqlDbType.Int, 4);
            SqlParameter prmMethodName = new SqlParameter("@MethodName", SqlDbType.NVarChar, 150);
            SqlParameter prmSecuritySetting = new SqlParameter("@SecuritySetting", SqlDbType.NVarChar, 100);
            SqlParameter prmCompanyName = new SqlParameter("@CompanyName", SqlDbType.NVarChar, 100);
            SqlParameter prmApplicationName = new SqlParameter("@ApplicationName", SqlDbType.NVarChar, 100);
            SqlParameter prmFirstGrouping = new SqlParameter("@FirstGrouping", SqlDbType.NVarChar, 100);
            SqlParameter prmSecondGrouping = new SqlParameter("@SecondGrouping", SqlDbType.NVarChar, 100);
            SqlParameter prmMethodDescription = new SqlParameter("@MethodDescription", SqlDbType.NVarChar, 100);

            prmPortalID.Value = objIWEBMethodInfo.Portal;
            prmMethodName.Value = objIWEBMethodInfo.MethodName;
            prmSecuritySetting.Value = objIWEBMethodInfo.SecuritySetting;
            prmCompanyName.Value = objIWEBMethodInfo.CompanyName;
            prmApplicationName.Value = objIWEBMethodInfo.ApplicationName;
            prmFirstGrouping.Value = objIWEBMethodInfo.FirstGrouping;
            prmSecondGrouping.Value = objIWEBMethodInfo.SecondGrouping;
            prmMethodDescription.Value = objIWEBMethodInfo.MethodDescription;

            DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), prmPortalID, prmMethodName, prmMethodDescription, prmSecuritySetting, prmCompanyName, prmApplicationName, prmFirstGrouping, prmSecondGrouping);
        }

        #endregion

        #region '"GetAssemblies"'
        public static List<IWEBMethodInfo> GetAssemblies()
        {
            List<IWEBMethodInfo> IWEBMethodInfoList = new List<IWEBMethodInfo>();
            IWEBMethodInfo IWEBMethodInfo;
            System.Web.Services.WebMethodAttribute WebMethodAttribute;

            Type objType = null;
            objType = BuildManager.GetType("DotNetNuke.Modules.IWebCSharp.WebService", true, true);

            MethodInfo[] arrMethodInfo;
            arrMethodInfo = objType.GetMethods();

            foreach (MethodInfo objMethodInfo in arrMethodInfo)
            {
                if (((objMethodInfo.IsHideBySig == false & objMethodInfo.IsSpecialName == false) | (objMethodInfo.IsHideBySig == true & objMethodInfo.IsSpecialName == false)))
                {
                    if ((!(objMethodInfo.Module.Name.ToLower() == "mscorlib.dll") & !(objMethodInfo.Module.Name.ToLower() == "system.dll")))
                    {
                        IWEBMethodInfo = new IWEBMethodInfo();
                        IWEBMethodInfo.MethodName = objMethodInfo.Name;
                        if (Attribute.IsDefined(objMethodInfo, typeof(System.Web.Services.WebMethodAttribute)))
                        {
                            WebMethodAttribute = (System.Web.Services.WebMethodAttribute)Attribute.GetCustomAttribute(objMethodInfo, typeof(System.Web.Services.WebMethodAttribute));
                            IWEBMethodInfo.MethodDescription = WebMethodAttribute.Description;
                        }
                        IWEBMethodInfoList.Add(IWEBMethodInfo);
                    }
                }
            }

            return IWEBMethodInfoList;

        }

        #endregion

        #region '"GetMethodsInDatabase"'
        public static IWEBMethodInfo GetMethodInDatabase(int PortalID, string MethodName)
        {
            IWEBMethodInfo IWEBMethodInfo = new IWEBMethodInfo();

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("SELECT PortalID, MethodName, MethodDescription, SecuritySetting, CompanyName, ApplicationName, FirstGrouping, SecondGrouping ");
            mySqlString.Append("FROM {databaseOwner}{objectQualifier}IWebCSharpMethods ");
            mySqlString.Append("WHERE PortalID = '" + PortalID + "' ");
            mySqlString.Append("AND MethodName = '" + MethodName + "' ");

            using (IDataReader dr = ((IDataReader)(DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), null))))
            {
                while (dr.Read())
                {
                    IWEBMethodInfo.MethodName = Convert.ToString(dr["MethodName"]);
                    IWEBMethodInfo.Portal = Convert.ToInt32(dr["PortalID"]);
                    IWEBMethodInfo.MethodDescription = Convert.ToString(dr["MethodDescription"]);
                    IWEBMethodInfo.SecuritySetting = Convert.ToString(dr["SecuritySetting"]);
                    IWEBMethodInfo.CompanyName = Convert.ToString(dr["CompanyName"]);
                    IWEBMethodInfo.ApplicationName = Convert.ToString(dr["ApplicationName"]);
                    IWEBMethodInfo.FirstGrouping = Convert.ToString(dr["FirstGrouping"]);
                    IWEBMethodInfo.SecondGrouping = Convert.ToString(dr["SecondGrouping"]);
                }
            }


            return IWEBMethodInfo;
        }

        public static List<IWEBMethodInfo> GetMethodsInDatabase()
        {
            List<IWEBMethodInfo> IWEBMethodInfoList = new List<IWEBMethodInfo>();

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("SELECT PortalID, MethodName, MethodDescription, SecuritySetting, CompanyName, ApplicationName, FirstGrouping, SecondGrouping ");
            mySqlString.Append("FROM {databaseOwner}{objectQualifier}IWebCSharpMethods ");

            mySqlString.Append("ORDER BY PortalID, MethodName ");

            using (IDataReader dr = ((IDataReader)(DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), null))))
            {
                while (dr.Read())
                {
                    IWEBMethodInfo IWEBMethodInfo = new IWEBMethodInfo();
                    IWEBMethodInfo.MethodName = Convert.ToString(dr["MethodName"]);
                    IWEBMethodInfo.Portal = Convert.ToInt32(dr["PortalID"]);
                    IWEBMethodInfo.MethodDescription = Convert.ToString(dr["MethodDescription"]);
                    IWEBMethodInfo.SecuritySetting = Convert.ToString(dr["SecuritySetting"]);
                    IWEBMethodInfo.CompanyName = Convert.ToString(dr["CompanyName"]);
                    IWEBMethodInfo.ApplicationName = Convert.ToString(dr["ApplicationName"]);
                    IWEBMethodInfo.FirstGrouping = Convert.ToString(dr["FirstGrouping"]);
                    IWEBMethodInfo.SecondGrouping = Convert.ToString(dr["SecondGrouping"]);
                    IWEBMethodInfoList.Add(IWEBMethodInfo);
                }
            }

            return IWEBMethodInfoList;
        }

        public ArrayList GetMethodsInDatabase(int Portal)
        {
            ArrayList IWEBMethodInfoList = new ArrayList();

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("SELECT MethodName ");
            mySqlString.Append("FROM {databaseOwner}{objectQualifier}IWebCSharpMethods ");
            mySqlString.Append("Where PortalID = " + Portal + " ");

            using (IDataReader dr = ((IDataReader)(DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), null))))
            {
                while (dr.Read())
                {
                    IWEBMethodInfoList.Add(Convert.ToString(dr["MethodName"]));
                }
            }

            return IWEBMethodInfoList;
        }

        #endregion

        #region '"PortalsOnServer"'
        public Array PortalsOnServer()
        {
            ArrayList arrPortals;
            PortalInfo colPortalInfo = new PortalInfo();
            PortalController colPortalController = new PortalController();
            arrPortals = colPortalController.GetPortals();
            int[] arrPortalIds = new int[arrPortals.Count];

            for (int i = 0; i <= (arrPortals.Count - 1); i++)
            {
                colPortalInfo = ((PortalInfo)(arrPortals[i]));
                arrPortalIds[i] = colPortalInfo.PortalID;
            }

            Array.Sort(arrPortalIds);
            return arrPortalIds;
        }

        #endregion

        #region '"ExtractGroup"'
        private string ExtractGroup(string Description, string Delimiter)
        {

            // * = Company Name
            // |= Application Name
            // # = First Grouping
            // ! = Second Grouping
            string strExtractGroup = "";
            int intFirstDelimiter = 0;
            int intSecondDelimiter = 0;

            //  No description was passed
            //  or it's length is too short to contain information
            if ((Description == "") | (Description.Length < 3))
            {
                return strExtractGroup;
            }

            // find first Delimiter
            intFirstDelimiter = Description.IndexOf(Delimiter);

            // Delimiter was not found 
            // or it is more than the second to the last character
            if ((intFirstDelimiter == -1) | (intFirstDelimiter > Description.Length - 2))
            {
                return strExtractGroup;
            }

            intSecondDelimiter = Description.IndexOf(Delimiter, intFirstDelimiter + 1);

            // Delimiter was not found 
            if ((intSecondDelimiter == -1))
            {
                return strExtractGroup;
            }

            // Extract data
            strExtractGroup = Description.Substring((intFirstDelimiter + 1), (intSecondDelimiter - (intFirstDelimiter + 1)));

            return Strings.Left(strExtractGroup, 100);
        }

        #endregion

        #region '"UpdateSecuritySetting"'
        public static void UpdateSecuritySetting(int PortalID, string MethodName, string SecuritySetting)
        {

            StringBuilder mySqlString = new StringBuilder();
            mySqlString.Append("Update {databaseOwner}{objectQualifier}IWebCSharpMethods ");
            mySqlString.Append("SET SecuritySetting = '" + SecuritySetting + "' ");
            mySqlString.Append("Where (PortalID = " + PortalID + ") ");
            mySqlString.Append("AND (MethodName = '" + MethodName + "') ");

            DotNetNuke.Data.DataProvider.Instance().ExecuteSQL(mySqlString.ToString(), null);
        }

        #endregion

    }

}

